home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Libraries / CDragAcrossTable 1.0b1 / CDragAcrossTask.c < prev    next >
Text File  |  1993-11-04  |  10KB  |  350 lines

  1. /******************************************************************************
  2.  CDragAcrossTask.c
  3.  
  4.     AUTHOR: Andrew_Gilmartin@Brown.Edu
  5.     MODIFIED: 93-11-04
  6.  
  7.     This global mouse task is used in conjunction with a CDragAcrossTable to
  8.     provide the user feedback while selecting the boundaries along which to 
  9.     move the selected cells or place a new object/cell.
  10.  
  11.     Copyright (C) 1993 by Brown University. All rights reserved.
  12.  
  13.     Permission is granted to any individual or institution to use, copy,
  14.     or redistribute the binary version of this software and its
  15.     documentation provided this notice and the copyright notices are
  16.     retained.  Permission is granted to any individual or non-profit
  17.     institution to use, copy, modify, or redistribute the source files
  18.     of this software provided this notice and the copyright notices are
  19.     retained.  This software may not be distributed for profit, either
  20.     in original form or in derivative works, nor can the source be
  21.     distributed to other than an individual or a non-profit institution.
  22.     Any  individual or group interested in seeing and/or using these
  23.     source files but who are prevented from doing so by the above
  24.     constraints should contact Don Wolfe, Vice-President for Computer 
  25.     Systems at Brown University, (401) 863-7247, for possible
  26.     software licensing of the source developed at Brown.
  27.  
  28.     Brown University and Andrew James Gilmartin make no representations
  29.     about the suitability of this software for any purpose.
  30.  
  31.      BROWN UNIVERSITY AND ANDREW JAMES GILMARTIN GIVE NO WARRANTY, EITHER
  32.     EXPRESS OR IMPLIED, FOR THE PROGRAM AND/OR DOCUMENTATION PROVIDED,
  33.     INCLUDING, WITHOUT LIMITATION, WARRANTY OF MERCHANTABILITY AND
  34.     WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE.
  35.  
  36. ******************************************************************************/
  37.  
  38. #include "ForgetRgn.h"
  39. #include "CDragAcrossTable.h"
  40. #include "CDragAcrossTask.h"
  41.  
  42.  
  43.  
  44. /******************************************************************************
  45.  IDragTable
  46.  
  47.     Initialize the task.
  48. ******************************************************************************/
  49.  
  50. void CDragAcrossTask::IDragAcrossTask
  51.     ( CDragAcrossTable* aTable
  52.     , RgnHandle aSelectionRgn
  53.     , short aNameIndex )
  54. {
  55.     IGlobalMouseTask( aNameIndex );
  56.  
  57.     itsFromTable = itsToTable = aTable;
  58.  
  59.     itsSelectionRgn = aSelectionRgn;
  60.     isSelectionRgnVisible = FALSE;
  61.  
  62. } /* IDragAcrossTask */
  63.  
  64.  
  65.  
  66. /******************************************************************************
  67.  Dispose
  68.  
  69.     Dispose of the drag region and then the rest.
  70. ******************************************************************************/
  71.  
  72. void CDragAcrossTask::Dispose( void )
  73. {
  74.     ForgetRgn( itsSelectionRgn );
  75.     
  76.     inherited::Dispose();
  77.  
  78. } /* Dispose */
  79.  
  80.  
  81.  
  82. /******************************************************************************
  83.  BeginTracking
  84.  
  85.     Begin tracking the mouse.
  86. ******************************************************************************/
  87.  
  88. void CDragAcrossTask::BeginTracking( Point startPt )
  89. {
  90.     Boundary hitBoundaries;
  91.  
  92.     FindHitBoundaries( itsFromTable, startPt, &hitBoundaries );
  93.     itsToBoundaries = hitBoundaries;
  94.     
  95.     itsToTable->Prepare();
  96.     itsToTable->SelectBoundaries( itsToBoundaries );
  97.     DrawSelectionRgn( TRUE );
  98.  
  99. } /* BeginTracking */
  100.  
  101.  
  102.  
  103. /******************************************************************************
  104.  KeepTracking
  105.  
  106.     The code here is a mixture of screen updating and hit finding. The logical
  107.     sequence is 
  108.     
  109.         hide the selection region, 
  110.         deselect the previous boundaries,
  111.         find the hit table, 
  112.         find the hit boundaries, 
  113.         select the current boundaries, and then
  114.         draw the selection region. 
  115.     
  116.     However, following this sequence in order does a log of drawing and makes 
  117.     for a very flickering screen. So the logical sequence is coded to minimize 
  118.     the amount of screen redraw. It does work but it is really ugly.
  119. ******************************************************************************/
  120.  
  121. void CDragAcrossTask::KeepTracking( Point currPt, Point prevPt, Point startPt )
  122. {
  123.     CDragAcrossTable* hitTable;
  124.     Boundary hitBoundaries;
  125.     Boolean hideBoundary;
  126.     Boolean showBoundary; 
  127.     Boolean moveSelection; 
  128.     Boolean hideSelection; 
  129.     Boolean showSelection;
  130.     Boolean autoScrolled;
  131.  
  132.         /* Do we have to un-draw the previous boundaries? */
  133.     
  134.     hitTable = FindHitTable( currPt );        
  135.     if ( hitTable )
  136.     {
  137.         FindHitBoundaries( hitTable, currPt, &hitBoundaries );
  138.         autoScrolled = AutoScroll( hitTable, currPt );
  139.     }
  140.     else
  141.     {
  142.         hitBoundaries = kEmptyBoundary;
  143.     }
  144.  
  145.         /* Figure out what needs to be drawn */
  146.  
  147.     hideBoundary = itsToTable != NULL && itsToTable != hitTable;
  148.     showBoundary = hitTable != NULL 
  149.         && ( itsToTable != hitTable || ! EqualPt( itsToBoundaries, hitBoundaries ) );
  150.  
  151.     moveSelection = ! EqualPt( currPt, prevPt );
  152.     hideSelection = moveSelection || showBoundary || hideBoundary;
  153.     showSelection = autoScrolled || ! hideSelection;
  154.  
  155.     if ( hideSelection )
  156.         DrawSelectionRgn( FALSE );
  157.  
  158.     if ( hideBoundary )
  159.     {
  160.         itsToTable->Prepare();
  161.         itsToTable->SelectBoundaries( kEmptyBoundary );
  162.     }
  163.     
  164.     if ( showBoundary )
  165.     {
  166.         hitTable->Prepare();
  167.         hitTable->SelectBoundaries( hitBoundaries );
  168.     }
  169.  
  170.     if ( moveSelection )
  171.         OffsetRgn( itsSelectionRgn, currPt.h - prevPt.h, currPt.v - prevPt.v );
  172.  
  173.     if ( showSelection )
  174.         DrawSelectionRgn( TRUE );
  175.  
  176.     itsToTable = hitTable;
  177.     itsToBoundaries = hitBoundaries;
  178.  
  179. //    if ( autoScrolled )
  180. //    {
  181. //        long ticks;
  182. //        Delay( PAGE_DELAY, &ticks );
  183. //    }
  184.  
  185. } /* KeepTracking */
  186.  
  187.  
  188.  
  189. /******************************************************************************
  190.  EndTracking
  191.  
  192.     Notify the CDragAcrossTable should the user have selected a boundary.
  193. ******************************************************************************/
  194.  
  195. void CDragAcrossTask::EndTracking( Point currPt, Point prevPt, Point startPt )
  196. {
  197.         /* Hide and dispose of the selection region */
  198.  
  199.     DrawSelectionRgn( FALSE );
  200.  
  201.     if ( itsToTable != NULL )
  202.     {
  203.         itsToTable->SelectBoundaries( kEmptyBoundary );
  204.         itsFromTable->MoveSelection( itsToTable, itsToBoundaries );
  205.     }
  206.  
  207. } /* EndTracking */
  208.  
  209.  
  210.  
  211. /******************************************************************************
  212.  DrawSelectionRgn
  213.  
  214.     Draw the selection region. Since this method is used to both show and hide
  215.     the region, isSelectionRgnVisible keeps track of when the region should
  216.     really be draw.
  217. ******************************************************************************/
  218.  
  219. void CDragAcrossTask::DrawSelectionRgn( Boolean showRgn )
  220. {
  221.         /* Is the visability changing? */
  222.  
  223.     if ( isSelectionRgnVisible != showRgn )
  224.     {
  225.         PenState penState;
  226.  
  227.             /* Draw on the desktop */
  228.             
  229.         gDesktop->Prepare();
  230.         
  231.         GetPenState( &penState );
  232.     
  233.         PenPat( gray );
  234.         PenMode( srcXor );
  235.         FrameRgn( itsSelectionRgn );
  236.     
  237.         SetPenState( &penState );
  238.         
  239.             /* Remember its visability */
  240.             
  241.         isSelectionRgnVisible = showRgn;
  242.     }
  243.  
  244. } /* DrawSelectionRgn */
  245.  
  246.  
  247.  
  248. /******************************************************************************
  249.  FindHitTable
  250.  
  251.     Finding the drag table is similar to dispatching the cursor. Infact, the 
  252.     code below is taken from DispatchCursor() and friends. Given a point in 
  253.     global coordinates first find the enclosing window and then find the 
  254.     sub-view that is a CDragAcrossTable.
  255.     
  256.     (There should be some means of finding not just a CDragAcrossTable, but a 
  257.     particular subclass. This could be done by keeping a list of tables to 
  258.     check. At the end of FindHitTable() it would check that the table found
  259.     is amoung the listed tables.)
  260. ******************************************************************************/
  261.  
  262. CDragAcrossTable* CDragAcrossTask::FindHitTable( Point mousePt )
  263. {
  264.     WindowPtr macWindow;
  265.     CView* hitView;
  266.  
  267.         /* Which Macintosh window? */
  268.         
  269.     if ( FindWindow( mousePt, &macWindow ) != inContent )
  270.         return NULL;
  271.  
  272.         /* Is it a TCL window? */
  273.         
  274.     if ( ((WindowPeek) macWindow)->windowKind != OBJ_WINDOW_KIND )
  275.         return NULL;
  276.  
  277.         /* Find sub-view that is a CDragAcrossTable */
  278.  
  279.     hitView = (CWindow*) GetWRefCon( macWindow );
  280.     
  281.     hitView->Prepare();            // Use Window's port and coords
  282.     GlobalToLocal( &mousePt );    // Convert mouse location in event
  283.  
  284.     do
  285.     {
  286.         hitView = hitView->FindSubview(mousePt);
  287.     
  288.     } while ( hitView != NULL && ! member( hitView, CDragAcrossTable ) );
  289.         
  290.         /* Done */
  291.  
  292.     return (CDragAcrossTable*) hitView;
  293.  
  294. } /* FindHitTable */
  295.  
  296.  
  297.  
  298. /******************************************************************************
  299.  FindHitBoundaries
  300.  
  301.     A utility method to convert the given point from global to the table's
  302.     local coordinates and return info on the boundaries hit.
  303. ******************************************************************************/
  304.  
  305. void CDragAcrossTask::FindHitBoundaries
  306.     ( CDragAcrossTable* aTable
  307.     , Point hitPt
  308.     , Boundary* hitBoundary )
  309. {
  310.     LongPt tablePt;
  311.  
  312.     aTable->Prepare();    
  313.     GlobalToLocal( &hitPt );    
  314.     aTable->QDToFrame( hitPt, &tablePt );
  315.  
  316.     aTable->FindBoundaries( &tablePt, hitBoundary );
  317.  
  318. } /* FindHitBoundaries */
  319.  
  320.  
  321.  
  322. /******************************************************************************
  323.  AutoScroll
  324.  
  325.     A utility method to convert the given point from global to the table's
  326.     local coordinates and auto-scroll if necessary. The selection region is
  327.     hidden if scrolling is to occure.
  328. ******************************************************************************/
  329.  
  330. Boolean CDragAcrossTask::AutoScroll( CDragAcrossTable* aTable, Point hitPt )
  331. {
  332.     LongPt tablePt;
  333.  
  334.     aTable->Prepare();    
  335.     GlobalToLocal( &hitPt );    
  336.     aTable->QDToFrame( hitPt, &tablePt );
  337.  
  338.     if ( aTable->ShouldScroll( &tablePt, NULL ) )
  339.     {
  340.         DrawSelectionRgn( FALSE );
  341.         return aTable->AutoScroll( &tablePt );
  342.     }
  343.  
  344.     return FALSE;
  345.  
  346. } /* AutoScroll */
  347.  
  348.  
  349.  
  350.